/*
本文件名：core.cpp
https://gitee.com/wu-org/neutron-star/blob/master/core.cpp

它是基于C++的《观天道》游戏的引擎。
在Linux环境下执行：
g++ -std=c++17 -pthread -Wall -O2 core.cpp -o core && ./core 
即可。或者直接在当前目录下执行make命令也可以，构建和运行一体。


游戏设计文档 (Game Design Document - GDD)
https://gitee.com/wu-org/databank/blob/master/docs/GDD.md


版本历史：
v0 名为core.cpp的空白源文件
v1 在v0基础上实现Tao1虚拟机(https://gitee.com/wu-org/databank/blob/master/server/ISA/TAO1.rkt)。
v2 在v1基础上将虚拟机的内存通过mmap映射到文件上。
v3 在v2基础上通过模板参数实现VM的不同8位16位32位64位版本。
v4 在v3基础上实现Tao2虚拟机(https://gitee.com/wu-org/databank/blob/zsh/server/ISA/Tao2.rkt)。
    opname          opcode
    -------------------------------
    NOP			    #x0 
                        
    PUSH			0x1 
    POP			    0x2 
                        
    ADD			    0x11
    SUB			    0x12
    MUL			    0x13
    DIV			    0x14
    MOD			    0x15
                        
    AND			    0x21
    OR			    0x22
    NOT			    0x23
                        
    EQ			    0x31
    GT			    0x32
    LT			    0x33
                        
    LOAD            0x41
    STORE		    0x42
    LOAD_INDIRECT   0x43
    STORE_INDIRECT  0x44
                        
    JUMP			0x51
    JUMPIF		    0x52
                        
    PRINT		    0x61
                        
    HALT			0xff

v5 保留v4的全部逻辑，但是消除编译时warning:
    g++ -std=c++17 -pthread -Wall -O2 -o core core.cpp
    core.cpp: In instantiation of ‘bool VirtualMachine<WORD_SIZE>::step_machine() [with long unsigned int WORD_SIZE = 32]’:
    core.cpp:443:18:   required from ‘void VirtualMachine<WORD_SIZE>::run() [with long unsigned int WORD_SIZE = 32]’
    core.cpp:929:11:   required from ‘void run_virtual_machine(const string&) [with unsigned char n = 32; std::string = std::__cxx11::basic_string<char>]’
    core.cpp:954:40:   required from here
    core.cpp:906:28: warning: comparison of integer expressions of different signedness: ‘const int’ and ‘VirtualMachine<32>::WordType’ {aka ‘unsigned int’} [-Wsign-compare]
    906 |             if (instr.code == instr_code) {
        |                 ~~~~~~~~~~~^~~~~~~~~~~~~
    core.cpp: In instantiation of ‘bool VirtualMachine<WORD_SIZE>::step_machine() [with long unsigned int WORD_SIZE = 64]’:
    core.cpp:443:18:   required from ‘void VirtualMachine<WORD_SIZE>::run() [with long unsigned int WORD_SIZE = 64]’
    core.cpp:929:11:   required from ‘void run_virtual_machine(const string&) [with unsigned char n = 64; std::string = std::__cxx11::basic_string<char>]’
    core.cpp:957:40:   required from here
    core.cpp:906:28: warning: comparison of integer expressions of different signedness: ‘const int’ and ‘VirtualMachine<64>::WordType’ {aka ‘long unsigned int’} [-Wsign-compare]
    core.cpp: In instantiation of ‘void VirtualMachine<WORD_SIZE>::debug_print() [with long unsigned int WORD_SIZE = 32]’:
    core.cpp:900:9:   required from ‘bool VirtualMachine<WORD_SIZE>::step_machine() [with long unsigned int WORD_SIZE = 32]’
    core.cpp:443:18:   required from ‘void VirtualMachine<WORD_SIZE>::run() [with long unsigned int WORD_SIZE = 32]’
    core.cpp:929:11:   required from ‘void run_virtual_machine(const string&) [with unsigned char n = 32; std::string = std::__cxx11::basic_string<char>]’
    core.cpp:954:40:   required from here
    core.cpp:891:28: warning: comparison of integer expressions of different signedness: ‘const int’ and ‘VirtualMachine<32>::WordType’ {aka ‘unsigned int’} [-Wsign-compare]
    891 |             if (instr.code == instr_code && instr.args > 0) {
        |                 ~~~~~~~~~~~^~~~~~~~~~~~~
    core.cpp: In instantiation of ‘void VirtualMachine<WORD_SIZE>::debug_print() [with long unsigned int WORD_SIZE = 64]’:
    core.cpp:900:9:   required from ‘bool VirtualMachine<WORD_SIZE>::step_machine() [with long unsigned int WORD_SIZE = 64]’
    core.cpp:443:18:   required from ‘void VirtualMachine<WORD_SIZE>::run() [with long unsigned int WORD_SIZE = 64]’
    core.cpp:929:11:   required from ‘void run_virtual_machine(const string&) [with unsigned char n = 64; std::string = std::__cxx11::basic_string<char>]’
    core.cpp:957:40:   required from here
    core.cpp:891:28: warning: comparison of integer expressions of different signedness: ‘const int’ and ‘VirtualMachine<64>::WordType’ {aka ‘long unsigned int’} [-Wsign-compare]
    core.cpp: In function ‘int main()’:
    core.cpp:969:11: warning: ignoring return value of ‘int system(const char*)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
    969 |     system((std::string("hexdump -C -n 4096 ") + base_path + std::string("/chunk_000.bin")).c_str());
        |     ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

v6  6.1 在v5基础上实现汇编代码从外部输入，而不是硬编码在core.cpp里：
    g++ -std=c++17 -pthread -Wall -O2 core.cpp -o core
    rm -rf vm_memory/
    ./core --asm asm/prime.asm | tee output.txt

    6.2 修改汇编器，使得支持汇编代码中0xab这样的十六进制表示


v7  调整assemble使汇编指令大小写不敏感。
v8  在v7基础上调整assemble使汇编代码中的标签也大小写不敏感。
现在要做:
v9  9.1 在v8基础上调整debug_print，使instr: 显示成S-EXP。

      */ 

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <filesystem>
#include <fstream>
#include <cstring>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <system_error>
#include <functional>
#include <map>
#include <set>
#include <cstdint>
#include <limits> 

namespace banker {

constexpr size_t CHUNK_SIZE = 4 * 1024 * 1024; // 4MB
constexpr size_t NUM_CHUNKS = 256; // 256 chunks = 1GB

// 异常类，用于包装系统错误
class MemoryMapException : public std::runtime_error {
public:
    MemoryMapException(const std::string& msg, int errno_val)
        : std::runtime_error(msg + ": " + std::strerror(errno_val)), error_code(errno_val) {}
    
    int code() const { return error_code; }
    
private:
    int error_code;
};

// 管理延迟映射的内存区域
class LazyMappedMemory {
public:
    explicit LazyMappedMemory(const std::string& base_path) : base_path(base_path) {
        // 确保基础目录存在
        std::filesystem::create_directories(base_path);
        
        // 初始化映射和文件描述符
        mappings.resize(NUM_CHUNKS, nullptr);
        file_descriptors.resize(NUM_CHUNKS, -1);
    }
    
    ~LazyMappedMemory() {
        // 清理所有映射和文件描述符
        for (size_t i = 0; i < NUM_CHUNKS; ++i) {
            if (mappings[i] != nullptr) {
                munmap(mappings[i], CHUNK_SIZE);
            }
            if (file_descriptors[i] != -1) {
                close(file_descriptors[i]);
            }
        }
    }
    
    // 禁用拷贝和移动
    LazyMappedMemory(const LazyMappedMemory&) = delete;
    LazyMappedMemory& operator=(const LazyMappedMemory&) = delete;
    LazyMappedMemory(LazyMappedMemory&&) = delete;
    LazyMappedMemory& operator=(LazyMappedMemory&&) = delete;
    
    uint8_t get_byte(size_t offset) {
        if (offset >= CHUNK_SIZE * NUM_CHUNKS) {
            return 0;
        }
        
        const size_t chunk_idx = offset / CHUNK_SIZE;
        const size_t chunk_offset = offset % CHUNK_SIZE;
        
        std::shared_lock lock(mutex);
        
        // 如果映射不存在，尝试创建或返回0
        if (mappings[chunk_idx] == nullptr) {
            lock.unlock(); // 释放共享锁，获取独占锁
            std::unique_lock unique_lock(mutex);
            
            // 双重检查，防止竞态条件
            if (mappings[chunk_idx] == nullptr) {
                try {
                    ensure_mapping(chunk_idx, false);
                } catch (const MemoryMapException&) {
                    // 文件不存在，返回0
                    return 0;
                }
            }
            unique_lock.unlock();
            lock.lock(); // 重新获取共享锁
        }
        
        return static_cast<uint8_t*>(mappings[chunk_idx])[chunk_offset];
    }
    
    void set_byte(size_t offset, uint8_t value) {
        if (offset >= CHUNK_SIZE * NUM_CHUNKS) {
            return;
        }
        
        const size_t chunk_idx = offset / CHUNK_SIZE;
        const size_t chunk_offset = offset % CHUNK_SIZE;
        
        std::unique_lock lock(mutex);
        
        // 确保映射存在（如果需要则创建文件）
        if (mappings[chunk_idx] == nullptr) {
            ensure_mapping(chunk_idx, true);
        }
        
        // 写入数据
        static_cast<uint8_t*>(mappings[chunk_idx])[chunk_offset] = value;
        
        // 标记块为脏
        dirty_chunks.insert(chunk_idx);
    }
    
    // 读取64位值
    int64_t get_int64(size_t offset) {
        int64_t value = 0;
        for (int i = 0; i < 8; ++i) {
            value |= static_cast<int64_t>(get_byte(offset + i)) << (i * 8);
        }
        return value;
    }
    
    // 写入64位值
    void set_int64(size_t offset, int64_t value) {
        for (int i = 0; i < 8; ++i) {
            set_byte(offset + i, (value >> (i * 8)) & 0xFF);
        }
    }
    
    // 将所有修改刷新到磁盘
    void flush_all() {
        std::shared_lock lock(mutex);
        for (size_t i = 0; i < NUM_CHUNKS; ++i) {
            if (mappings[i] != nullptr) {
                msync(mappings[i], CHUNK_SIZE, MS_SYNC);
            }
        }
        dirty_chunks.clear();
    }
    
    // 刷新所有脏块到磁盘
    void flush_dirty_chunks() {
        std::unique_lock lock(mutex);
        for (auto chunk_idx : dirty_chunks) {
            if (mappings[chunk_idx] != nullptr) {
                msync(mappings[chunk_idx], CHUNK_SIZE, MS_SYNC);
            }
        }
        dirty_chunks.clear();
    }
    
    // 将指定块刷新到磁盘
    void flush_chunk(size_t chunk_idx) {
        if (chunk_idx >= NUM_CHUNKS) {
            return;
        }
        
        std::shared_lock lock(mutex);
        if (mappings[chunk_idx] != nullptr) {
            msync(mappings[chunk_idx], CHUNK_SIZE, MS_SYNC);
        }
        dirty_chunks.erase(chunk_idx);
    }
    
    // 卸载指定块（释放内存映射）
    void unload_chunk(size_t chunk_idx) {
        if (chunk_idx >= NUM_CHUNKS) {
            return;
        }
        
        std::unique_lock lock(mutex);
        if (mappings[chunk_idx] != nullptr) {
            munmap(mappings[chunk_idx], CHUNK_SIZE);
            mappings[chunk_idx] = nullptr;
        }
        dirty_chunks.erase(chunk_idx);
        // 注意：我们保留文件描述符以便后续快速重新映射
    }
    
private:
    void ensure_mapping(size_t chunk_idx, bool create_if_missing) {
        if (chunk_idx >= NUM_CHUNKS) {
            throw std::out_of_range("Chunk index out of range");
        }
        
        const std::string file_path = base_path + "/chunk_" + 
                                    (chunk_idx < 10 ? "00" : 
                                     chunk_idx < 100 ? "0" : "") + 
                                    std::to_string(chunk_idx) + ".bin";
        
        // 检查文件是否存在
        if (!std::filesystem::exists(file_path)) {
            if (!create_if_missing) {
                throw MemoryMapException("File does not exist", ENOENT);
            }
            
            // 创建文件并初始化为全零
            int fd = open(file_path.c_str(), O_RDWR | O_CREAT, 0644);
            if (fd == -1) {
                throw MemoryMapException("Failed to create file", errno);
            }
            
            // 设置文件大小为 CHUNK_SIZE
            if (ftruncate(fd, CHUNK_SIZE) == -1) {
                close(fd);
                throw MemoryMapException("Failed to truncate file", errno);
            }
            
            // 初始化文件内容为全零
            std::vector<uint8_t> zeros(CHUNK_SIZE, 0);
            if (write(fd, zeros.data(), zeros.size()) == -1) {
                close(fd);
                throw MemoryMapException("Failed to initialize file", errno);
            }
            
            file_descriptors[chunk_idx] = fd;
        } else if (file_descriptors[chunk_idx] == -1) {
            // 文件存在但尚未打开
            int fd = open(file_path.c_str(), O_RDWR);
            if (fd == -1) {
                throw MemoryMapException("Failed to open file", errno);
            }
            file_descriptors[chunk_idx] = fd;
        }
        
        // 创建内存映射
        void* mapping = mmap(nullptr, CHUNK_SIZE, PROT_READ | PROT_WRITE, 
                            MAP_SHARED, file_descriptors[chunk_idx], 0);
        if (mapping == MAP_FAILED) {
            throw MemoryMapException("Failed to map memory", errno);
        }
        
        mappings[chunk_idx] = mapping;
    }
    
    std::string base_path;
    std::vector<void*> mappings;
    std::vector<int> file_descriptors;
    std::set<size_t> dirty_chunks; // 跟踪哪些块被修改了
    mutable std::shared_mutex mutex;
};

// 提供线程安全版本的包装器
class ThreadSafeLazyMappedMemory {
public:
    explicit ThreadSafeLazyMappedMemory(const std::string& base_path)
        : impl(std::make_shared<LazyMappedMemory>(base_path)) {}
    
    uint8_t get_byte(size_t offset) {
        return impl->get_byte(offset);
    }
    
    void set_byte(size_t offset, uint8_t value) {
        impl->set_byte(offset, value);
    }
    
    int64_t get_int64(size_t offset) {
        return impl->get_int64(offset);
    }
    
    void set_int64(size_t offset, int64_t value) {
        impl->set_int64(offset, value);
    }
    
    void flush_all() {
        impl->flush_all();
    }
    
    void flush_dirty_chunks() {
        impl->flush_dirty_chunks();
    }
    
private:
    std::shared_ptr<LazyMappedMemory> impl;
};

} // namespace banker

// 虚拟机实现
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <mutex>
#include <shared_mutex>
#include <filesystem>
#include <fstream>
#include <cstring>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <system_error>
#include <functional>
#include <map>
#include <set>
#include <cstdint>
#include <type_traits>
#include <iomanip>
#include <stack>
#include <deque>
#include <cassert>

// utils
// 辅助函数：将字符串转换为大写
std::string to_upper(const std::string& str) {
    std::string result = str;
    std::transform(result.begin(), result.end(), result.begin(), ::toupper);
    return result;
}

// 模板化的虚拟机实现
// 虚拟机实现 - 模板化版本
template <size_t WORD_SIZE>
class VirtualMachine {
private:
    // 根据字长选择合适的数据类型
    using WordType = typename std::conditional<WORD_SIZE == 8, uint8_t,
                     typename std::conditional<WORD_SIZE == 16, uint16_t,
                     typename std::conditional<WORD_SIZE == 32, uint32_t,
                     uint64_t>::type>::type>::type;
    
    // 常量定义
    static const int MEM_LEN = 512;
    static const int CODE_SEG_BEGIN = 0;
    static const int CODE_SEG_LEN = 256;
    static const int DATA_SEG_BEGIN = 256;
    static const int DATA_SEG_LEN = 256;
    static const int COINS_REMAIN_INIT = 2618;
    
    // 全局状态
    banker::ThreadSafeLazyMappedMemory memory;
    int PC = 0;

    class: public std::deque<WordType> {
        public:
            WordType pop() {
                WordType value = this->front();
                this->pop_front();
                return value;
            }
            void push(WordType value) {
                this->push_front(value);
            }
    } REGSTACK;

    int CYCLES = 0;
    int COINS_REMAIN = COINS_REMAIN_INIT;
    
    // 指令定义
    struct Instruction {
        std::string name;
        WordType code;
        int args;
        std::function<void()> action;
    };
    std::vector<Instruction> ISA{
        {"NOP",  0x0, 0, [this]() { PC += 1; }},
        {"PUSH", 0x1, 1, [this]() { 
            WordType arg = read_code(PC + 1);
            REGSTACK.push(arg);
            PC += 2;
        }},
        {"POP", 0x2, 0, [this]() { 
            assert(REGSTACK.size() >= 1);
            REGSTACK.pop(); 
            PC += 1;
        }},
        {"ADD", 0x11, 0, [this]() { 
            assert(REGSTACK.size() >= 1);
            WordType op2 = REGSTACK.pop();
            WordType op1 = REGSTACK.pop();
            REGSTACK.push(op1 + op2);
            PC += 1;
        }},
        {"SUB", 0x12, 0, [this]() { 
            assert(REGSTACK.size() >= 2);
            WordType op2 = REGSTACK.pop();
            WordType op1 = REGSTACK.pop();
            REGSTACK.push(op1 - op2);
            PC += 1;
        }},
        {"MUL", 0x13, 0, [this]() { 
            assert(REGSTACK.size() >= 2);
            WordType op2 = REGSTACK.pop();
            WordType op1 = REGSTACK.pop();
            REGSTACK.push(op1 * op2);
            PC += 1;
        }},
        {"DIV", 0x14, 0, [this]() { 
            assert(REGSTACK.size() >= 2);
            WordType op2 = REGSTACK.pop();
            WordType op1 = REGSTACK.pop();

            assert(op2 != 0);
            REGSTACK.push(op1 / op2);
            PC += 1;
        }},
        {"MOD", 0x15, 0, [this]() { 
            assert(REGSTACK.size() >= 2);
            WordType op2 = REGSTACK.pop();
            WordType op1 = REGSTACK.pop();
            assert(op2 != 0);
            REGSTACK.push(op1 % op2);
            PC += 1;
        }},
        {"AND", 0x21, 0, [this]() { 
            assert(REGSTACK.size() >= 2);
            WordType op2 = REGSTACK.pop();
            WordType op1 = REGSTACK.pop();
            REGSTACK.push(op1 & op2);
            PC += 1;
        }},
        {"OR", 0x22, 0, [this]() { 
            assert(REGSTACK.size() >= 2);
            WordType op2 = REGSTACK.pop();
            WordType op1 = REGSTACK.pop();
            REGSTACK.push(op1 | op2);
            PC += 1;
        }},
        {"NOT", 0x23, 0, [this]() { 
            assert(REGSTACK.size() >= 1);
            WordType op1 = REGSTACK.pop();
            REGSTACK.push(~op1);
            PC += 1;
        }},
        {"EQ", 0x31, 0, [this]() { 
            assert(REGSTACK.size() >= 2);
            WordType op2 = REGSTACK.pop();
            WordType op1 = REGSTACK.pop();
            REGSTACK.push(op1 == op2 ? 1 : 0);
            PC += 1;
        }},
        {"GT", 0x32, 0, [this]() { 
            assert(REGSTACK.size() >= 2);
            WordType op2 = REGSTACK.pop();
            WordType op1 = REGSTACK.pop();
            REGSTACK.push(op1 > op2 ? 1 : 0);
            PC += 1;
        }},
        {"LT", 0x33, 0, [this]() { 
            assert(REGSTACK.size() >= 2);
            WordType op2 = REGSTACK.pop();
            WordType op1 = REGSTACK.pop();
            REGSTACK.push(op1 < op2 ? 1 : 0);
            PC += 1;
        }},
        {"LOAD", 0x41, 1, [this]() { 
            int addr = read_code(PC + 1);
            REGSTACK.push(get_data(addr));
            PC += 2;
        }},
        {"STORE", 0x42, 1, [this]() { 
            int addr = read_code(PC + 1);
            assert(REGSTACK.size() >= 1);
            set_data(addr, REGSTACK.pop());
            PC += 2;
        }},
        {"LOAD_INDIRECT", 0x43, 0, [this]() { 
            assert(REGSTACK.size() >= 1);
            int addr = REGSTACK.pop();
            REGSTACK.push(get_data(addr));
            PC += 1;
        }},
        {"STORE_INDIRECT", 0x44, 0, [this]() { 
            assert(REGSTACK.size() >= 2);
            WordType addr = REGSTACK.pop();
            int val  = REGSTACK.pop();
            set_data(addr, val);
            PC += 1;
        }},
        {"JUMP", 0x51, 1, [this]() { 
            PC = read_code(PC + 1);
        }},
        {"JUMPIF", 0x52, 1, [this]() { 
            if (REGSTACK.empty()) {
                PC += 2;
            } else {
                WordType condition = REGSTACK.pop();
                if (condition == 0) {
                    PC += 2;
                } else {
                    PC = read_code(PC + 1);
                }
            }
        }},
        {"PRINT", 0x61, 0, [this]() { 
            if (!REGSTACK.empty()) {
                std::cout << static_cast<uint64_t>(REGSTACK.pop()) << std::endl;
            }
            PC += 1;
        }},
        {"HALT", 0xff, 0, [this]() {}}
    };

    std::map<std::string, std::string> ALIAS_MAP{
        {"+", "ADD"}, {"-", "SUB"}, {"*", "MUL"}, {"/", "DIV"}, {"%", "MOD"},
        {"=", "EQ"}, {">", "GT"}, {"<", "LT"},
        {"&", "AND"}, {"|", "OR"}, {"~", "NOT"},
        {"JMP", "JUMP"}, {"HLT", "HALT"}
    };
public:
    VirtualMachine(const std::string& base_path) : memory(base_path) {}
    
    void run() {
        // 加载测试代码
        // load_test_code();
        
        // 运行机器
        while (COINS_REMAIN > 0 && PC >= 0 && PC < MEM_LEN) {
            if (!step_machine()) {
                break; // 遇到HALT指令
            }
            CYCLES++;
            
            if (PC >= MEM_LEN) {
                PC = 0;
            }
        }
        
        if (COINS_REMAIN <= 0) {
            std::cout << "NOT-ENOUGH-COINS" << std::endl;
        }
        dump_machine();
    }

    VirtualMachine<WORD_SIZE>& load_assembly_code(const std::vector<std::string>& assembly_code) {
        // 汇编代码并加载到内存
        auto bytecode = assemble(assembly_code);
        for (size_t i = 0; i < bytecode.size() && i < CODE_SEG_LEN; i++) {
            // 根据字长计算字节偏移量
            size_t byte_offset = (CODE_SEG_BEGIN + i) * (WORD_SIZE / 8);
            
            if constexpr (WORD_SIZE == 8) {
                memory.set_byte(byte_offset, bytecode[i]);
            } else if constexpr (WORD_SIZE == 16) {
                // 将16位值分解为两个字节存储
                memory.set_byte(byte_offset, bytecode[i] & 0xFF);
                memory.set_byte(byte_offset + 1, (bytecode[i] >> 8) & 0xFF);
            } else if constexpr (WORD_SIZE == 32) {
                // 将32位值分解为四个字节存储
                for (int j = 0; j < 4; ++j) {
                    memory.set_byte(byte_offset + j, (bytecode[i] >> (j * 8)) & 0xFF);
                }
            } else { // 64位
                memory.set_int64(byte_offset, bytecode[i]);
            }
        }
        return *this;
    }
private:
    // 基本设施
    WordType read_code(int addr) {
        // 根据字长计算字节偏移量
        size_t byte_offset = (CODE_SEG_BEGIN + addr) * (WORD_SIZE / 8);
        
        if constexpr (WORD_SIZE == 8) {
            return memory.get_byte(byte_offset);
        } else if constexpr (WORD_SIZE == 16) {
            // 读取两个字节并组合成16位值
            uint16_t low = memory.get_byte(byte_offset);
            uint16_t high = memory.get_byte(byte_offset + 1);
            return (high << 8) | low;
        } else if constexpr (WORD_SIZE == 32) {
            // 读取四个字节并组合成32位值
            uint32_t value = 0;
            for (int i = 0; i < 4; ++i) {
                value |= static_cast<uint32_t>(memory.get_byte(byte_offset + i)) << (i * 8);
            }
            return value;
        } else { // 64位
            return memory.get_int64(byte_offset);
        }
    }
    
    WordType get_data(int addr) {
        // 根据字长计算字节偏移量
        size_t byte_offset = (DATA_SEG_BEGIN + addr) * (WORD_SIZE / 8);
        
        if constexpr (WORD_SIZE == 8) {
            return memory.get_byte(byte_offset);
        } else if constexpr (WORD_SIZE == 16) {
            // 读取两个字节并组合成16位值
            uint16_t low = memory.get_byte(byte_offset);
            uint16_t high = memory.get_byte(byte_offset + 1);
            return (high << 8) | low;
        } else if constexpr (WORD_SIZE == 32) {
            // 读取四个字节并组合成32位值
            uint32_t value = 0;
            for (int i = 0; i < 4; ++i) {
                value |= static_cast<uint32_t>(memory.get_byte(byte_offset + i)) << (i * 8);
            }
            return value;
        } else { // 64位
            return memory.get_int64(byte_offset);
        }
    }
    
    void set_data(int addr, WordType val) {
        // 根据字长计算字节偏移量
        size_t byte_offset = (DATA_SEG_BEGIN + addr) * (WORD_SIZE / 8);
        
        if constexpr (WORD_SIZE == 8) {
            memory.set_byte(byte_offset, val);
        } else if constexpr (WORD_SIZE == 16) {
            // 将16位值分解为两个字节存储
            memory.set_byte(byte_offset, val & 0xFF);
            memory.set_byte(byte_offset + 1, (val >> 8) & 0xFF);
        } else if constexpr (WORD_SIZE == 32) {
            // 将32位值分解为四个字节存储
            for (int i = 0; i < 4; ++i) {
                memory.set_byte(byte_offset + i, (val >> (i * 8)) & 0xFF);
            }
        } else { // 64位
            memory.set_int64(byte_offset, val);
        }
    }
    
    WordType get_arg() {
        return read_code(PC + 1);
    }
    
    WordType get_instr() {
        return read_code(PC);
    }
    
    // 简单的汇编器
    std::vector<WordType> assemble(const std::vector<std::string>& tokens) {
        // 简化的汇编器实现
        std::vector<WordType> result;
        std::map<std::string, int> labels;
        
        // 第一遍：收集标签
        int addr = 0;
        for (size_t i = 0; i < tokens.size(); i++) {
            const std::string& token = tokens[i];
            if (token.back() == ':') {
                std::string label_name = token.substr(0, token.size() - 1);
                label_name = to_upper(label_name);
                labels[label_name] = addr;
            } else {
                // 查找指令或别名
                std::string token_upper = to_upper(token);
                std::string actual_name = token_upper;
                if (ALIAS_MAP.find(token_upper) != ALIAS_MAP.end()) {
                    actual_name = ALIAS_MAP[token_upper];
                }
                // 查找指令
                for (const auto& instr : ISA) {
                    if (instr.name == actual_name) {
                        addr++;
                        if (instr.args > 0) {
                            i++;
                            addr++;
                        }
                        break;
                    }
                }
            }
        }
        
        // 第二遍：生成代码
        for (size_t i = 0; i < tokens.size(); i++) {
            const std::string& token = tokens[i];
            if (token.back() == ':') {
                continue; // 跳过标签定义
            }
            
            // 查找指令或别名
            std::string token_upper = to_upper(token);
            std::string actual_name = token_upper;
            if (ALIAS_MAP.find(token_upper) != ALIAS_MAP.end()) {
                actual_name = ALIAS_MAP[token_upper];
            }
            
            // 查找指令
            for (const auto& instr : ISA) {
                if (instr.name == actual_name) {
                    result.push_back(instr.code);
                    
                    if (instr.args > 0) {
                        i++;
                        if (i < tokens.size()) {
                            const std::string& arg = tokens[i];
                            std::string arg_upper = to_upper(arg);
                            if (labels.find(arg_upper) != labels.end()) {
                                result.push_back(labels[arg_upper]);
                            } else {
                                try {
                                    // 支持十六进制表示法 (0x前缀)
                                    if (arg.size() > 2 && arg[0] == '0' && (arg[1] == 'x' || arg[1] == 'X')) {
                                        result.push_back(std::stoi(arg.substr(2), nullptr, 16));
                                    } else {
                                        result.push_back(std::stoi(arg));
                                    }
                                } catch (...) {
                                    result.push_back(0);
                                }
                            }
                        } else {
                            result.push_back(0);
                        }
                    }
                    break;
                }
            }
        }
        return result;
    }
    
    // 调试函数
    void dump_machine() {
        std::cout << "((CODE-SEG-BEGIN " << CODE_SEG_BEGIN << ")" << std::endl;
        std::cout << " (CODE-SEG-LEN " << CODE_SEG_LEN << ")" << std::endl;
        std::cout << " (DATA-SEG-BEGIN " << DATA_SEG_BEGIN << ")" << std::endl;
        std::cout << " (DATA-SEG-LEN " << DATA_SEG_LEN << ")" << std::endl;
        std::cout << " (PC " << PC << ")" << std::endl;
        std::cout << " (REGSTACK (";
        for (size_t i = 0; i < REGSTACK.size(); i++) {
            if (i > 0) std::cout << " ";
            std::cout << static_cast<uint64_t>(REGSTACK[i]);
        }
        std::cout << "))" << std::endl;
        std::cout << " (COINS-REMAIN " << COINS_REMAIN << ")" << std::endl;
        std::cout << " (CYCLES " << CYCLES << "))" << std::endl;
    }
    
    void debug_print() {
        std::map<int, std::string> dasm_map;
        for (const auto& instr : ISA) {
            dasm_map[instr.code] = instr.name;
        }
        
        WordType instr_code = get_instr();
        std::string instr_name = dasm_map.count(instr_code) ? dasm_map[instr_code] : "UNKNOWN";
        
        std::cout << "(CYCLES: " << CYCLES << " PC: " << PC << " REGSTACK: (";
        for (size_t i = 0; i < REGSTACK.size(); i++) {
            if (i > 0) std::cout << " ";
            std::cout << static_cast<uint64_t>(REGSTACK[i]);
        }
        std::cout << ") instr: (" << instr_name;
        
        for (const auto& instr : ISA) {
            if (instr.code == instr_code && instr.args > 0) {
                std::cout << " " << static_cast<uint64_t>(get_arg());
                break;
            }
        }
        std::cout << "))" << std::endl;
    }
    
    bool step_machine() {
        debug_print();
        
        WordType instr_code = get_instr();
        
        // 查找并执行指令
        for (const auto& instr : ISA) {
            if (instr.code == instr_code) {
                // 执行指令
                instr.action();
                
                // 确保指令的原子性：刷新所有脏块到磁盘
                memory.flush_dirty_chunks();
                
                COINS_REMAIN--;
                return instr_code != 255; // 如果不是HALT指令，返回true
            }
        }
        
        // 未知指令，跳过
        PC += 1;
        COINS_REMAIN--;
        return true;
    }
};

// 辅助函数，用于创建特定字长的虚拟机
template <uint8_t n>
void run_virtual_machine(const std::string& base_path) {
    VirtualMachine<n> vm(base_path);
    vm.run();
}

#include <fstream>

int main(int argc, char** argv) {
    const std::string base_path = "./vm_memory";
    
    std::string asm_file_path;
    std::vector<std::string> assembly_tokens; // 改为存储token而不是整行

    // 解析命令行参数
    for (int i = 1; i < argc; i++) {
        std::string arg = argv[i];
        if (arg == "--asm" && i + 1 < argc) {
            asm_file_path = argv[++i];
        }
    }

    try {
        if (!asm_file_path.empty()) {
            // 从文件读取汇编代码
            std::ifstream asm_file(asm_file_path);
            if (!asm_file.is_open()) {
                throw std::runtime_error("无法打开汇编文件: " + asm_file_path);
            }
            
            std::string line;
            while (std::getline(asm_file, line)) {
                // 移除注释和空白
                size_t comment_pos = line.find(';');
                if (comment_pos != std::string::npos) {
                    line = line.substr(0, comment_pos);
                }
                
                line.erase(0, line.find_first_not_of(" \t\r\n"));
                line.erase(line.find_last_not_of(" \t\r\n") + 1);
                
                if (!line.empty()) {
                    // 分割行中的token
                    std::istringstream iss(line);
                    std::string token;
                    while (iss >> token) {
                        assembly_tokens.push_back(token);
                    }
                }
            }
            asm_file.close();
        } else {
            // 从标准输入读取汇编代码（向后兼容）
            std::string line;
            while (std::getline(std::cin, line)) {
                // 移除注释和空白
                size_t comment_pos = line.find(';');
                if (comment_pos != std::string::npos) {
                    line = line.substr(0, comment_pos);
                }
                
                line.erase(0, line.find_first_not_of(" \t\r\n"));
                line.erase(line.find_last_not_of(" \t\r\n") + 1);
                
                if (!line.empty()) {
                    // 分割行中的token
                    std::istringstream iss(line);
                    std::string token;
                    while (iss >> token) {
                        assembly_tokens.push_back(token);
                    }
                }
            }
        }
        
        if (assembly_tokens.empty()) {
            std::cout << "No assembly code provided, using built-in test code." << std::endl;
            VirtualMachine<64> vm(base_path);
            vm.run();
        } else {
            // 清除输入重定向后的 EOF 状态
            if (!std::cin.good()) {
                std::cin.clear();
                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            }

            // 选择虚拟机类型
            std::cout << "Select virtual machine type:" << std::endl;
            std::cout << "1. 8-bit" << std::endl;
            std::cout << "2. 16-bit" << std::endl;
            std::cout << "3. 32-bit" << std::endl;
            std::cout << "4. 64-bit" << std::endl;
            std::cout << "Enter your choice (1-4): ";
            
            int choice;
            if (!(std::cin >> choice)) {
                std::cout << "Invalid input. Running 64-bit VM by default." << std::endl;
                VirtualMachine<64> vm(base_path);
                vm.load_assembly_code(assembly_tokens); // 需要添加这个方法
                vm.run();
            } else {
                switch (choice) {
                    case 1: {
                        VirtualMachine<8>(base_path)
                            .load_assembly_code(assembly_tokens)
                            .run();
                        break;
                    }
                    case 2: {
                        VirtualMachine<16>(base_path)
                            .load_assembly_code(assembly_tokens)
                            .run();
                        break;
                    }
                    case 3: {
                        VirtualMachine<32>(base_path)
                            .load_assembly_code(assembly_tokens)
                            .run();
                        break;
                    }
                    case 4: {
                        VirtualMachine<64>(base_path)
                            .load_assembly_code(assembly_tokens)
                            .run();
                        break;
                    }
                    default:
                        std::cout << "Invalid choice. Running 64-bit VM by default." << std::endl;
                        VirtualMachine<64>(base_path)
                            .load_assembly_code(assembly_tokens)
                            .run();
                        break;
                }
            }
        }
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    
    int result = system((std::string("hexdump -C -n 4096 ") + base_path + std::string("/chunk_000.bin")).c_str());
    (void)result;

    return 0;

#if 0
一些小工具：
od -t u1 -N 256 vm_memory/chunk_000.bin
od -v -An -w1 -t u1 -N 89 vm_memory/chunk_000.bin | sed 's/^ *//'
#endif
}